<!DOCTYPE html>
<html>
<head>
	<title>Poker</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<script type="text/javascript" src="js/jquery-3.2.0.min.js"></script>
</head>
<style type="text/css">
	#playTable{float:left;width:900px;height:800px;border:1px solid #dedede;}
	#ruleTable{width:400px;float:left;    position: fixed;right: 0px;top:50px;}
	#cardStack{text-align:center;line-height:100px;font-size:20px;margin-bottom:10px;width:80px;height:100px;border:1px solid #dcdcdc;}
	#usedStack{text-align:center;line-height:100px;font-size:20px;margin-bottom:10px;width:80px;height:100px;border:1px solid #dcdcdc;}
	#lastCards{}
	#playerCards1{}
	#playerCards2{}
	#playerCards3{}
	#playerCards4{}
	.current-player{background:#e6c2c2;}

	
	.play-card{    background: #88d8f1;color:white;border:1px solid #dcdcdc;width:60px;height:20px;float:left;text-align:center;line-height:20px;margin-left:1px;cursor:pointer;}
	.play-no-card{background:white;border:1px solid #dcdcdc;width:60px;height:20px;float:left;text-align:center;line-height:20px;margin-left:1px;cursor:pointer;}
	.player-hand{clear: both;margin-bottom:10px;width:100%;height:170px;border:1px solid #dcdcdc;}

	.card{margin-top: 15px;background:white;border:1px solid #dcdcdc;width:60px;height:80px;float:left;text-align:center;line-height:80px;margin-left:1px;cursor:pointer;}
	.card:hover{background:#dcdcdc;margin-top: 8px;}
	.card.picked{background:#dcdcdc;margin-top: 0px;}
</style>
<body>
	<div id="body">
		<div id="header"></div>
		<div id="menu"></div>
		<div id="playTable">
			<div class="stack">牌堆</div>
			<div class="player-hand" id="cardStack">?</div>
			<div class="stack">已出</div>
			<div class="player-hand" id="usedStack">0</div>
			<div class="stack">上一手牌</div>
			<div class="player-hand" id="lastCards">...</div>
			<div class="player"><span style="float:left;background:red;color:white">Player A</span><div class='play-card'>出牌</div><div class='play-no-card'>过</div></div>
			<div class="player-hand" id="playerCards1"></div>
			<div class="player"><span style="float:left;background:red;color:white">Player B</span><div class='play-card'>出牌</div><div class='play-no-card'>过</div></div>
			<div class="player-hand" id="playerCards2"></div>
			<div class="player"><span style="float:left;background:red;color:white">Player C</span><div class='play-card'>出牌</div><div class='play-no-card'>过</div></div>
			<div class="player-hand" id="playerCards3"></div>
			<div class="player"><span style="float:left;background:red;color:white">Player D</span><div class='play-card'>出牌</div><div class='play-no-card'>过</div></div>
			<div class="player-hand" id="playerCards4"></div>
		</div>
		<div id="ruleTable">
			游戏规则（跑得快）：
			<br/>
			1. 牌堆为一副牌去掉大小王。
			<br/>
			2. 四人各发13张牌。
			<br/>
			3. 不可连对、顺子最少5张。
			<br/>
			4. 四张为炸弹，炸弹可不带或带任意一张。
			<br/>
			5. 可三带二（不一定是对子）或不带。（暂时不能带1张，即使是最后的牌目前也不行）。
		</div>
	</div>

</body>

<script>
	var tempCardStack = [];
	var cardStack = [];
	var usedCardStack = [];
	var lastCards = []; // 当前牌面上的牌
	var playerCards1=[];
	var playerCards2 = [];
	var playerCards3 = [];
	var playerCards4 = [];
	var currentPlayer = 1; 
	var lastPlayer = 1; // 当前牌面上是谁打出的牌

	var playerCardTable1 = document.getElementById("playerCards1");
	var playerCardTable2 = document.getElementById("playerCards2");
	var playerCardTable3 = document.getElementById("playerCards3");
	var playerCardTable4 = document.getElementById("playerCards4");

	// 扑克牌图片映射(n+1).jpg
	var imageRelation = ["jokerA","jokerB","2-3","2-4","2-5","2-6","2-7","2-8","2-9","2-10","2-11","2-12","2-13","2-14","2-15",
	"1-3","1-4","1-5","1-6","1-7","1-8","1-9","1-10","1-11","1-12","1-13","1-14","1-15",
	"4-3","4-4","4-5","4-6","4-7","4-8","4-9","4-10","4-11","4-12","4-13","4-14","4-15",
	"3-3","3-4","3-5","3-6","3-7","3-8","3-9","3-10","3-11","3-12","3-13","3-14","3-15"];

	// 1: 红桃 2: 黑桃 3: 方片 4：草花
	// 1~13
	// special: 大王jokerA 小王jokerB
	// var specialCards = ['joberA','jokerB'];
	var colorArr = [1,2,3,4];

	$(document).ready(function(){
		for(var i =0;i<4;i++){
			// A 2 按照大小为14、15，若改变规则，则可以回到1、2
			for(var j=3;j<=15;j++){
				tempCardStack.push(colorArr[i]+"-"+j);
			}
		}

		randomSort(tempCardStack,cardStack);

		// 发起手牌
		sendCard(playerCards1,13);
		sendCard(playerCards2,13);
		sendCard(playerCards3,13);
		sendCard(playerCards4,13);

		sortByCardOrder(playerCards1);
		sortByCardOrder(playerCards2);
		sortByCardOrder(playerCards3);
		sortByCardOrder(playerCards4);

		refreshTable();

		$("#playerCards"+currentPlayer).addClass("current-player");
	});
	

	

	// 对数组随机排序
	function randomSort(arr, newArr) {
		// 如果原数组arr的length值等于1时，原数组只有一个值，其键值为0
		// 同时将这个值push到新数组newArr中
		if(arr.length == 1) {
			newArr.push(arr[0]);
			return newArr; // 相当于递归退出
		}
		// 在原数组length基础上取出一个随机数
		var random = Math.ceil(Math.random() * arr.length) - 1;
		// 将原数组中的随机一个值push到新数组newArr中
		newArr.push(arr[random]);
		// 对应删除原数组arr的对应数组项
		arr.splice(random,1);
		return randomSort(arr, newArr);
	}

	// 对数组按牌面大小排序
	function sortByCardOrder(arr) {

		if(arr.length == 1) {
			return false;
		}

		arr.sort(function(a,b){
			m = a.split("-");
			n = b.split("-");
            return Number(n[1])-Number(m[1])
        });
	}

	// 给某人牌堆发n张牌
	function sendCard(playerCardsArr,n){
		for(var i=0;i<n;i++){
			playerCardsArr.push(cardStack.pop());
		}
	}

	// 出牌
	function playCard(playerCardsArr,cardsArr){
		// 如果有牌打出
		if(cardsArr.length>0){
			lastCards = [];
			for(var i=0;i<cardsArr.length;i++){
				playerCardsArr.splice($.inArray(cardsArr[i], playerCardsArr), 1);
				lastCards.push(cardsArr[i]);
			}
			usedCardStack.push(lastCards);
			lastPlayer=currentPlayer;
			refreshTable();
			if(playerCardsArr.length<=0){
				win(currentPlayer);
			}
		}
		
		currentPlayer = currentPlayer%4+1;
		$(".current-player").removeClass("current-player");
		$("#playerCards"+currentPlayer).addClass("current-player");
	}

	// 刷新牌桌
	function refreshTable(){
		var html ="";
		for(var n=1;n<=4;n++){
			var playerCards = eval("playerCards"+n);
			var playerCardTable = eval("playerCardTable"+n);
			for(var i=0;i<playerCards.length;i++){
				imgHtml = "<img class='poker-img' src='images/pokers/"+((imageRelation.indexOf(playerCards[i]))+1)+".jpg'/>";
				html += "<div class='card' id='"+playerCards[i]+"'>"+imgHtml+"</div>";
			}
			html=html.replace(/-11</g,"-J<");
			html=html.replace(/-12</g,"-Q<");
			html=html.replace(/-13</g,"-K<");
			html=html.replace(/-14</g,"-A<");
			playerCardTable.innerHTML=html;
			html="";
		}
		// 刷新上一手牌
		for(var i=0;i<lastCards.length;i++){
			imgHtml = "<img class='poker-img' src='images/pokers/"+((imageRelation.indexOf(lastCards[i]))+1)+".jpg'/>";
			html += "<div class='card' id='"+lastCards[i]+"'>"+imgHtml+"</div>";
		}
		html=html.replace(/-11</g,"-J<");
		html=html.replace(/-12</g,"-Q<");
		html=html.replace(/-13</g,"-K<");
		html=html.replace(/-14</g,"-A<");
		$("#lastCards").html(html);

		// 刷新已出牌张数
		$("#usedStack").html(usedCardStack.length);
	}

	// 游戏胜利
	function win(user){
		var name = $(".player").eq(user-1).children("span").html();
		alert(name+" 获得了胜利！");
	}

	$(document).on("click",".card",function(e){
		var playerHand = $(this).parent(".player-hand");
		if(playerHand.attr("id").indexOf(currentPlayer)>0){
			if($(this).hasClass("picked")){
				$(this).removeClass("picked");
			}else{
				$(this).addClass("picked");
			}
		}
	});

	$(document).on("click",".play-card",function(e){
		var playerHand = $(this).parent(".player").next();
		if(playerHand.attr("id").indexOf(currentPlayer)>0){
			// 将含有picked的card的值拼成数组打出
			var playedCards = [];
			// 若没有选中牌，不可出牌
			if($(".picked").length<=0){
				alert("请选择要出的牌！");
				return false;
			}
			for(var i=0;i<$(".picked").length;i++){
				playedCards.push($(".picked").eq(i).attr("id"));
			}
			if(!canPlayJudge(playedCards)){
				alert("不可以这样出！");
				return false;
			}
			if(playerHand.attr("id").indexOf(lastPlayer)<=0){
				if(!canFollowJudge(playedCards)){
					alert("请出比牌面大的牌！");
					return false;
				}
			}
			
			playCard(eval(playerHand.attr("id")),playedCards);
		}
	});

	$(document).on("click",".play-no-card",function(e){
		var playerHand = $(this).parent(".player").next();
		// 如果是牌面上牌的出牌人，不可跳过
		if(playerHand.attr("id").indexOf(lastPlayer)>0){
			alert("没有人要你的牌，请出牌！");
			return false;
		}
		if(playerHand.attr("id").indexOf(currentPlayer)>0){
			var playedCards = [];
			playCard(eval(playerHand.attr("id")),playedCards);
		}
	});


	// 出牌规则判断
	function canPlayJudge(cards){
		var can = false;
		// 单张
		if(cards.length>11){
			return false;
		}
		if(cards.length==1){
			return true;
		}
		// 两、三、四张相同
		if(cards.length>=2 && cards.length<=4){
			return sameNumber(cards);
		}
		
		if(cards.length==5){
			// 五张顺子
			if(isStraight(cards)){
				return true;
			}
			// 四张相同＋任意一张、三张相同＋任意两张
			c = sameNumberCount(cards);
			console.log(c);
			if(sameNumberCount(cards)==4 || sameNumberCount(cards)==3){
				return true;
			}
		}
		
		// 6～11张顺子
		if(cards.length>=6 && cards.length<=11){
			if(isStraight(cards)){
				return true;
			}
		}
	}

	// 是否能够跟牌判断
	function canFollowJudge(cards){
		// 判断依据张数，分为两种：常规、炸弹
		if(lastCards.length!=cards.length){
			console.log("step1");
			// TODO:判断是否炸弹
			if(cards.length==4 || cards.length==5){
				if(sameNumberCount(cards)==4){
					return true;
				}
			}
		}else{
			// 1、2、3张时，一定是相同的，比第一张的大小
			console.log("step2");
			if(cards.length<=3){
				return Number(cards[0].split("-")[1])>Number(lastCards[0].split("-")[1]);
			}
			// 4张时：连对、炸弹
			// 5张时：三带二、顺子、炸弹带1
			// 6张时：顺子、三连对
			// >=7张：顺子
			// >7且偶数张：连对
			// >8且3的倍数张：连顺
		}

		// 单张
		if(cards.length>11){
			return false;
		}
		if(cards.length==1){
			return true;
		}
		// 两、三、四张相同
		if(cards.length>=2 && cards.length<=4){
			return sameNumber(cards);
		}
		
		if(cards.length==5){
			// 五张顺子
			if(isStraight(cards)){
				return true;
			}
			// 四张相同＋任意一张、三张相同＋任意两张
			if(sameNumberCount(cards)==4 || sameNumberCount(cards)==3){
				return true;
			}
		}
		
		// 6～11张顺子
		if(cards.length>=6 && cards.length<=11){
			if(isStraight(cards)){
				return true;
			}
		}
	}

	// 判断是否同数
	function sameNumber(cards){
		number = cards[0].split("-")[1];
		for(var i=0;i<cards.length;i++){
			if(cards[i].split("-")[1]!=number){
				return false;
			}
		}
		return true;
	}

	// 获取同数最多的出现次数
	function sameNumberCount(cards){
		numbers = [];
		counts = [];
		for(var i=0;i<cards.length;i++){
			n = cards[i].split("-")[1];
			index = $.inArray(n,numbers);
			if(index<0){
				numbers.push(n);
				counts.push(1);
			}else{
				counts[index]++;
			}
		}
		return Math.max.apply(null, counts);
	}

	// 判断是否是顺子
	function isStraight(cards){
		// 张数大于等于5
		if(cards<5){
			return false;
		}
		// 不包含jokerA、jokerB
		if($.inArray("jokerA",cards)>=0||$.inArray("jokerB",cards)>=0){
			return false;
		}
		// 建立数组
		numbers = [];
		for(var i=0;i<cards.length;i++){
			n = Number(cards[i].split("-")[1]);
			// 不能有2
			if(n==15){
				return false;
			}
			index = $.inArray(n,numbers);
			if(index<0){
				numbers.push(n);
			}else{
				// 不能有重复
				return false;
			}
		}
		return isContinuous(numbers);
	}

	// 判断数组中数值是否连续相邻
	function isContinuous(arr){
	    max = -1;
	    min = -1;
	    for (var i = 0; i < arr.length; i++)
	    {
	        if (arr[i] != 0)
	        {
	            if (arr[i] > max || max == -1) // 防止数组中的非0最大数还比 -1 小时，最终能取得真正的非0最大值。
	                max = arr[i];

	            if (arr[i] < min || min == -1) // 防止数组中的非0最小数还比 -1 大时，最终能取得真正的非0最小值。
	                min = arr[i];
	        }

	    }

	    if (max - min <= arr.length - 1)
	        return true;
	    else
	        return false;

	}


	// TODO:规则库，规则分两种，1.出牌规则 2.跟牌规则，先遍历判断出牌规则，再遍历判断跟牌规则
	
	
</script>
</html>